#coding: utf-8 
from floor import *
from worldPath import *

from doors import *
from room import *

import cPickle as pickle

class Building():
	floors={}
	activeFloor=None
	path=Paths()
	
	def __init__(self,parent,activeFloor):
		self.activeFloor=activeFloor
		self.cleanSim=parent
		self.parent=parent
		
		try:
			import psyco
			psyco.full()
		except ImportError:
			pass
			
		psyco.log()
		psyco.profile(0.2)
	
	def getNodeByName(self,name):
		nodes=[]
		for fname,floor in self.floors.iteritems():
			nodes+=floor.doors
			nodes+=floor.rooms
		
		for node in nodes:
			if node.name==name:
				return node
		
		return None
		
	def calcPathWeight(self,floor):
		#cria as ligações entre rooms e doors
		name_connections = floor.connections
		object_connections = []
		
		for room_name,door_name in name_connections:
			room=floor.getRoomBy(room_name)
			door=floor.doors[door_name]
			object_connections.append([room,door])
			object_connections.append([door,room])
		
		throwght_rooms_connections=[]
		
		for i in object_connections:
			for j in object_connections:
				if i[1] == j[0] and i[0] != j[1] and isinstance(i[1],Room):
					throwght_rooms_connections.append([i[0],j[1]])
		
		object_connections=object_connections+throwght_rooms_connections
		
		for node0,node1 in object_connections:
			self.path.connect(node0,node1,1)
		
		connection_graphs=[]
		for node0,node1 in object_connections:
			if isinstance(node0,Room):
				room=node0
			elif isinstance(node1,Room):
				room=node1
			else:
				room = self.path.findConnectiongRoom(node0,node1)
			
			weight=len(room.area.findPath(node0.pos,node1.pos))
			self.path.connect(node0,node1,weight)
			
			connection_graphs.append((node0.name,node1.name,weight))
			
		pickle.dump(connection_graphs, file(floor.name+"/"+floor.name+'_path.pkl', 'w'))
	
	def addFloor(self,floorName,number,scale):
		if number in self.floors.keys():
			print "Double declaration of the floor "+str(number)
		else:
			#adiciona elementos todos do piso
			self.floors[number]=Floor(self.parent,floorName,scale)
			floor = self.floors[number]

			#adiciona as doors e rooms aos nós do path
			for node in floor.doors+floor.rooms:
				if node.connected:
					self.path.addNode(node)

			try:
				connection_graphs = pickle.load(file(floorName+"/"+floorName+'_path.pkl'))
				
				for node0_name,node1_name,weight in connection_graphs:
					node0=self.getNodeByName(node0_name)
					node1=self.getNodeByName(node1_name)
					self.path.connect(node0,node1,weight)
				#~ print "foi de load"
					
			except:
				#~ pass
				#~ print "passou-se a frente o self.calcPathWeight(floor)"
				self.calcPathWeight(floor)
				#~ print "foi de save"
			
			
			
			print "Adicionado "+floorName+" no piso "+str(number)+"."

	@property
	def visibleFloor(self):
		if self.activeFloor == None:
			return None
		else:
			return self.floors[self.activeFloor]

	def runGA(self,pop=2,gener=2):
		rooms=[]
		for floor in self.floors.values():
			rooms+=floor.rooms
		
		for room in rooms:
			room.runGenOptim(population=pop,generations=gener)
			
	
	
	def update(self):
		for number,floor in self.floors.items():
			floor.update(visible=(self.activeFloor==number))

